package com.avalon.core.module;

import com.avalon.core.context.Context;
import com.avalon.core.exception.AvalonException;
import com.avalon.core.model.PrimaryKey;
import com.avalon.core.model.RecordRow;
import com.avalon.core.model.View;
import com.avalon.core.service.AbstractService;
import com.avalon.core.service.AbstractServiceList;
import com.avalon.core.util.Dom4jUtils;
import com.avalon.core.util.ObjectUtils;
import com.avalon.core.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;

@Slf4j
@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
public abstract class AbstractModule {
    @Autowired
    private Context context;

    public Context getContext() {
        return context;
    }

    public AbstractModule getModule() {
        return context.getModule(this.getClass());
    }

    public abstract String getModuleName();


    public abstract String getLabel();


    public abstract String getDescription();

    /// 安装之后，是否显示在菜单中
    public abstract Boolean getDisplay();

    /**
     * 模块图标
     *
     * @return url 本地文件
     */
    public String getIcon() {
        return null;
    }

    public AbstractServiceList getServiceList() {
        return context.getModuleMap().getModuleServiceList(getModuleName());
    }


    @PostConstruct
    public void postConstruct() {
        if (log.isDebugEnabled()) {
            log.debug("模块初始化->" + getModuleName());
        }
        try {
            if (context.getAvalonApplicationContext().isActive()) {
                String firstBeanName = context.getFirstBeanName(this.getClass());
                if (StringUtils.isNotEmpty(firstBeanName) && StringUtils.isNotEmpty(getModuleName())) {
                    context.registerAlias(firstBeanName, getModuleName());
                }
            }
        } catch (AvalonException e) {
            log.error("bean 注册别名失败,错误信息->" + e.getMessage());
            log.error(e.getMessage(), e);
        }
        getContext().addModule(this);
    }

    /**
     * 创建模块
     */
    public void createModule() {
        if (ObjectUtils.isNull(getServiceList())) return;
        PrimaryKey key = insertModuleInfo();
        for (AbstractService service : getServiceList()) {
            service.createTable();
            PrimaryKey serviceId = service.insertTableInfo(key);
            service.insertFieldInfo(serviceId);
        }

        try {
            View view = Dom4jUtils.loadModule(getModuleName());
            if (ObjectUtils.isNull(view)) {
                return;
            }

        } catch (DocumentException | AvalonException e) {
            e.printStackTrace();
        }
    }

    /**
     * 插入模块信息 到moduleService表中
     *
     * @return id
     */
    protected PrimaryKey insertModuleInfo() {
        RecordRow row = new RecordRow();
        row.put("name", getModuleName());
        row.put("label", getLabel());
        row.put("description", getDescription());
        row.put("display", getDisplay());
        row.put("icon", getIcon());
        row.put("isInstall", false);
        return context.getServiceBean("base.module").insert(row);
    }


    public void dropModule() {
        if (ObjectUtils.isNull(getServiceList())) return;

        for (AbstractService service : getServiceList()) {
            service.dropTable();
        }
    }

    public void upgradeModule() {
        if (ObjectUtils.isNull(getServiceList())) return;

        for (AbstractService service : getServiceList()) {
            service.upgradeTable();
        }
    }
}
